package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.BindTeachplanMediaDto;
import com.xuecheng.commons.model.dto.TeachplanDto;
import com.xuecheng.commons.model.vo.MediaVo;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.model.vo.TeachplanVo;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.domain.TeachplanMedia;
import com.xuecheng.content.mappers.TeachplanMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.TeachplanMediaService;
import com.xuecheng.content.service.TeachplanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.media.api.MediaClient;
import com.xuecheng.web.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程计划 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-07-17
 */
@Service
public class TeachplanServiceImpl extends ServiceImpl<TeachplanMapper, Teachplan> implements TeachplanService {
    @Autowired(required = false)
    TeachplanMapper teachplanMapper;

    @Autowired
    CourseBaseService courseBaseService;

    @Autowired
    MediaClient mediaClient;

    @Autowired
    TeachplanMediaService teachplanMediaService;
    //mbp提供功能强大的单表查询
    /*//课程计划列表-树形结构
    @Override
    public ResponseResult treeNodes(Long courseId) {
        //1.根据课程id，一次性查询所有的课程计划数据
        List<TeachplanVo> teachplanVos = teachplanMapper.treeNodes(courseId);
        //2.提取1级大纲，返回值
        TeachplanVo parent = null;
        for (TeachplanVo teachplanVo : teachplanVos) {
            if (teachplanVo.getGrade() == 1) {
                parent = teachplanVo;
            }
        }
        //3.提取2级大纲，设置到1级中
        List<TeachplanVo> twos = new ArrayList<>();
        for (TeachplanVo teachplanVo : teachplanVos) {
            if (teachplanVo.getGrade() == 2) {
                twos.add(teachplanVo);
            }
        }
        parent.setTeachPlanTreeNodes(twos);
        //4.循环所有的2级大纲，查询每个2级大纲下的3级
        for (TeachplanVo two : twos) {
            List<TeachplanVo> threes = new ArrayList<>();
            for (TeachplanVo teachplanVo : teachplanVos) {
                if (teachplanVo.getGrade() == 3 && teachplanVo.getParentid().equals(two.getId())) {
                    threes.add(teachplanVo);
                }
            }
            two.setTeachPlanTreeNodes(threes);
        }
        //5.返回值
        return ResponseResult.okResult(parent);
    }*/
    //课程计划列表-树形结构
    @Override
    public ResponseResult treeNodes(Long courseId) {
        //1.根据课程id，一次性查询所有的课程计划数据
        List<TeachplanVo> teachplanVos = teachplanMapper.treeNodes(courseId); //这就是查询所有课程计划，我们直接查询处status=1

        /*等一下
        你这样写不太好，有错误。
        你为什么补在查询所有课程计划数据的时候，直接指定一个status再查询呢
        */

        //2.提取1级大纲，返回值
        TeachplanVo parent = teachplanVos.stream()
                .filter(vo -> vo.getGrade() == 1)  //添加筛选条件
                .findFirst()
                .get();
        //3.提取2级大纲，设置到1级中
        List<TeachplanVo> twos = teachplanVos.stream()
                .filter(vo -> vo.getGrade() == 2)
                .collect(Collectors.toList());
        parent.setTeachPlanTreeNodes(twos);
        //4.循环所有的2级大纲，查询每个2级大纲下的3级
        for (TeachplanVo two : twos) {
            List<TeachplanVo> threes = teachplanVos.stream()
                    .filter(vo -> vo.getGrade() == 3 && vo.getParentid().equals(two.getId()))
                    .collect(Collectors.toList());
            two.setTeachPlanTreeNodes(threes);
        }
        //5.返回值
        return ResponseResult.okResult(parent);
    }

    //保存或者更新
    @Override
    @Transactional
    public ResponseResult saveOrUpdatePlan(TeachplanDto dto) {
        //1.判断课程状态
        //1.1 获取课程id
        Long courseId = dto.getCourseId();
        //1.2 查询课程
        CourseBase courseBase = courseBaseService.getById(courseId);
        //1.3 判断状态
        if (!courseBase.getAuditStatus().equals(CourseConstants.AUDIT_DISPAST_STATUS)
                && !courseBase.getAuditStatus().equals(CourseConstants.AUDIT_UNPAST_STATUS)) {
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }
        //2.处理ParentId为空的情况(保存2级大纲时)，查询1级大纲
        if (dto.getParentid() == null) {
            //保存2级课程计划，查询1级的课程计划
            LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
            qw.eq(Teachplan::getGrade, CourseConstants.FIRST_LEVEL);
            qw.eq(Teachplan::getCourseId, courseId);
            Teachplan parent = this.getOne(qw);
            //判断parent是否为空(略)
            dto.setParentid(parent.getId());
        }
        //将dto转化为Java实体类
        Teachplan teachplan = BeanHelper.copyProperties(dto, Teachplan.class);
        //3.判断保存的课程计划的id
        boolean flag = false;
        if (teachplan.getId() == null) {
            //3.1 ID不存在，保存,应该先保存入库，在查询有几个课程计划
            flag = this.save(teachplan);
            //如果是第三级计划，更新课程表的plan_num字段(作业)
            LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
            qw.eq(Teachplan::getStatus, CourseConstants.FIRST_LEVEL);
            qw.eq(Teachplan::getCourseId, courseId);
            qw.eq(Teachplan::getGrade,CourseConstants.THIRD_LEVEL);

            int count = teachplanMapper.selectList(qw).size();
            courseBase.setPlanNum(count);
            courseBaseService.updateById(courseBase);
        } else {
            //3.2 ID存在，更新
            flag = this.updateById(teachplan);
        }
        if (!flag) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        return ResponseResult.okResult();
    }

    //删除课程计划
    @Override
    public ResponseResult deleteById(Long id) {
        Long courseId = this.getById(id).getCourseId();
        CourseBase courseBase = courseBaseService.getById(courseId);
        boolean remove = this.removeById(id);
        if (!remove) {
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
        qw.eq(Teachplan::getStatus, CourseConstants.FIRST_LEVEL);
        qw.eq(Teachplan::getCourseId, courseId);
        qw.eq(Teachplan::getGrade,3);

        int count = teachplanMapper.selectList(qw).size();
        courseBase.setPlanNum(count);
        courseBaseService.updateById(courseBase);
        return ResponseResult.okResult();
    }

    //课程计划绑定媒资
    @Override
    public ResponseResult associationMedia(BindTeachplanMediaDto dto) {
        //1.判断基本参数
        if (dto.getMediaId() == null || dto.getTeachplanId() == null) {
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        //2.判断课程状态
        //2.1 查询课程计划
        Teachplan teachplan = this.getById(dto.getTeachplanId());
        //2.2 根据课程计划的课程id查询课程
        Long courseId = teachplan.getCourseId();
        CourseBase courseBase = courseBaseService.getById(courseId);
        //2.3 判断
        String auditStatus = courseBase.getAuditStatus();
        if (!CourseConstants.AUDIT_UNPAST_STATUS.equals(auditStatus) &&
                !CourseConstants.AUDIT_DISPAST_STATUS.equals(auditStatus)) {
            throw new BusinessException(ErrorCode.MEDIABINDERROR);
        }
        //3.调用feign接口，根据媒资id，查询媒资对象
        ResponseResult<MediaVo> result = mediaClient.findById(dto.getMediaId());
        MediaVo vo = result.getData();
        //4.查询媒资绑定数据(是否已经绑定)
        LambdaQueryWrapper<TeachplanMedia> qw = new LambdaQueryWrapper<>();
        qw.eq(TeachplanMedia::getTeachplanId,dto.getTeachplanId());
        TeachplanMedia teachplanMedia = teachplanMediaService.getOne(qw);
        if (teachplanMedia == null) {
        //4.1 不存在，保存数据
            teachplanMedia = new TeachplanMedia();
            teachplanMedia.setMediaFilename(vo.getFilename());
            teachplanMedia.setMediaId(vo.getId());
            teachplanMedia.setTeachplanId(dto.getTeachplanId());
            teachplanMedia.setCourseId(courseId);
            teachplanMedia.setCreateDate(new Date());
            teachplanMediaService.save(teachplanMedia);
        } else {
        //4.2 存在，更新数据
            teachplanMedia.setMediaFilename(vo.getFilename());
            teachplanMedia.setMediaId(vo.getId());
            teachplanMediaService.updateById(teachplanMedia);
        }
        return ResponseResult.okResult();
    }
}
